﻿namespace FlickrDownloadr.Features.Shell
{
    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using Autofac;
    using Caliburn.Micro;
    using FlickrDownloadr.Features.About;
    using FlickrDownloadr.Features.DownloadOptions;
    using FlickrDownloadr.Features.Search;
    using Microsoft.WindowsAPICodePack.Shell;

    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IShell, IViewAware
    {
        private IComponentContext _container;
        private SearchViewModel _searchView;

        public ShellViewModel()
        {
            //ShellObject shellObject = ShellObject.FromParsingName(@"");
            //_thumbnail = shellObject.Thumbnail.BitmapSource;
        }

        private BitmapSource _thumbnail;

        public BitmapSource Thumbnail
        {
            get { return _thumbnail; }
        }

        public ShellViewModel(IComponentContext container, SearchViewModel searchView)
        {
            _container = container;

            _searchView = searchView;

            DisplayName = "Flickr Downloadr v3";
        }

        protected override void OnInitialize()
        {
            base.OnInitialize();

            ActivateItem(_searchView);
        }


        private bool _isBusy;
        private bool goingBack;
        readonly Stack<IScreen> previous = new Stack<IScreen>();
        private readonly Image _imgSource = new Image();
        private readonly Image _imgTarget = new Image();
        private Storyboard _sb = new Storyboard();
        private bool _isNavigating = false;
        private bool _canGoForward = false;

        public bool CanGoBack
        {
            get { return previous.Count > 0; }
            set { throw new NotImplementedException(); }
        }

        public bool CanGoForward
        {
            get { return _canGoForward; }
            set {
                _canGoForward = value;
                NotifyOfPropertyChange(() => CanGoForward);
            }
        }

        public enum CurrentScreen
        {
            Search,
            Options,
            Downloading
        }

        private CurrentScreen GetCurrentScreen()
        {
            if (ActiveItem is DownloadOptionsViewModel)
            {
                return CurrentScreen.Options;
            }
            else if (ActiveItem is SearchViewModel)
            {
                return CurrentScreen.Search;
            }

            return CurrentScreen.Search;
        }

        public void GoForward()
        {
            var currentScreen = GetCurrentScreen();

            if (currentScreen == CurrentScreen.Search)
            {
                var downloadOptions = _container.Resolve<DownloadOptionsViewModel>();
                ActivateItem(downloadOptions);
            }
            else if (currentScreen == CurrentScreen.Downloading)
            {
                
            }
        }

        public void GoBack()
        {
            goingBack = true;
            ActivateItem(previous.Pop());
            goingBack = false;
        }

        //public void GoBack()
        //{
        //    if (_currentScreen == CurrentScreen.Options)
        //    {
        //        _currentScreen = CurrentScreen.Search;
        //        ActivateItem(_searchView);
        //    }
        //    else if (_currentScreen == CurrentScreen.Downloading)
        //    {
        //        var downloadOptions = _container.Resolve<DownloadOptionsViewModel>();
        //        ActivateItem(downloadOptions);
        //    }
        //}

        public override void CloseItem(IScreen item)
        {
            //base.CloseItem(item);
            GoBack();
        }

        protected override void ChangeActiveItem(IScreen newItem, bool closePrevious)
        {
            if (ActiveItem != null && !goingBack)
            {
                previous.Push(ActiveItem);
            }

            NotifyOfPropertyChange(() => CanGoBack);


            if (_isNavigating)
            {
                ResetTransition();
            }

            // Get the view and the parent control for the ContentControl.
            var view = (ShellView)GetView(null);

            if (ActiveItem == null)
            {
                base.ChangeActiveItem(newItem, closePrevious);
                return;
            }

            // Avoid re-opening the same item.
            if (ActiveItem.GetType() == newItem.GetType()) return;

            _isNavigating = true;

            UIElement sourceView = (UIElement)view.ActiveItem.Content;

            // Grid container
            var parent = view.ActiveItem.Parent as Panel;

            RenderTargetBitmap sourceBitmapRender = new RenderTargetBitmap((int)sourceView.RenderSize.Width, (int)sourceView.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
            sourceBitmapRender.Render(sourceView);
            WriteableBitmap sourceBitmap = new WriteableBitmap(sourceBitmapRender);
            _imgSource.Source = sourceBitmap;

            parent.Children.Add(_imgSource);

            // Activate the new screen
            base.ChangeActiveItem(newItem, closePrevious);
            //ActivateItem(screen);

            // Make sure we render the new view.
            parent.UpdateLayout();

            // Get the new view.
            UIElement targetView = (UIElement)view.ActiveItem.Content;


            RenderTargetBitmap targetBitmapRender = new RenderTargetBitmap((int)targetView.RenderSize.Width, (int)targetView.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
            targetBitmapRender.Render(targetView);
            WriteableBitmap targetBitmap = new WriteableBitmap(targetBitmapRender);
            _imgTarget.Source = targetBitmap;

            parent.Children.Add(_imgTarget);

            _sb = new Storyboard();
            _sb.Completed += new EventHandler(Storyboard_Completed);

            DoubleAnimation fadeAnimation = new DoubleAnimation();
            fadeAnimation.From = 0.0;
            fadeAnimation.To = 1.0;
            fadeAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(250));

            Storyboard.SetTarget(fadeAnimation, _imgTarget);
            Storyboard.SetTargetProperty(fadeAnimation, new PropertyPath(Rectangle.OpacityProperty));
            _sb.Children.Add(fadeAnimation);

            DoubleAnimation fadeAnimation2 = new DoubleAnimation();
            fadeAnimation2.From = 1.0;
            fadeAnimation2.To = 0.0;
            fadeAnimation2.Duration = new Duration(TimeSpan.FromMilliseconds(100));

            Storyboard.SetTarget(fadeAnimation2, _imgSource);
            Storyboard.SetTargetProperty(fadeAnimation2, new PropertyPath(Rectangle.OpacityProperty));
            _sb.Children.Add(fadeAnimation2);

            view.ActiveItem.Visibility = Visibility.Collapsed;

            _sb.Begin();
        }

        private void ResetTransition()
        {
            _isNavigating = false;

            var view = (ShellView)GetView(null);
            var parent = view.ActiveItem.Parent as Panel;

            parent.Children.Remove(_imgSource);
            parent.Children.Remove(_imgTarget);

            view.ActiveItem.Visibility = Visibility.Visible;

            _sb.Stop();
        }

        void Storyboard_Completed(object sender, EventArgs e)
        {
            ResetTransition();
        }

        public void About()
        {
            var aboutView = _container.Resolve<IAbout>();
            ActivateItem(aboutView);

            //Messenger.Default.Send<DisplayAboutMessage>(new DisplayAboutMessage(DialogOperations.Open));
        }

        public void Login()
        {
            var downloadOptions = _container.Resolve<DownloadOptionsViewModel>();
            ActivateItem(downloadOptions);
        }
    }
}
